home *** CD-ROM | disk | FTP | other *** search
/ Computer Music Interactif…cial Edition 1999 Winter / cd 3.iso / mac / Mac / Shares / Midishare™1.68 / Development Tools / Sources Examples / msDisplay / msDisplay.p < prev    next >
Encoding:
Text File  |  1992-03-08  |  27.6 KB  |  802 lines  |  [TEXT/MPS ]

  1. {[j=14/60/0]}
  2. {••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
  3. {•                                  DISPLAY                                     •}
  4. {•------------------------------------------------------------------------------•}
  5. {•                                                                                 •}
  6. {• Le programme DISPLAY présenté ici, fait partie d'une série d'exemples à         •}
  7. {• caractère pédagogique (enfin j'espère !) sur la façon d'utiliser MIDISHARE.    •}
  8. {•                                                                                 •}
  9. {• DISPLAY affiche en permanence et sans aucun filtrage les événements Midi     •}
  10. {• reçus. Les informations affichées sont la date : en heures, minutes, secondes•}
  11. {• et millièmes, la provenance : port et canal Midi, le type d'événement : note    •}
  12. {• keyOn, etc... et les données complémentaires : hauteur, vélocité, etc...        •}
  13. {•------------------------------------------------------------------------------•}
  14. {• Release 1.2 (Avril 90)                                                        •}
  15. {•            - bugs sous Multifinder (DAs, activations, idle)                    •}
  16. {•------------------------------------------------------------------------------•}
  17. {•        © GRAME 1989/90, Yann Orlarey et Hervé Lequay                            •}
  18. {••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
  19.  
  20.  
  21. Program Display;
  22.  
  23. USES    Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf, Traps, MIDIShareUnit;
  24.  
  25. const    AppleID    = 128;    AppleMenu    = 1;
  26.         FileID    = 129;    FileMenu    = 2;
  27.         EditID    = 130;    EditMenu    = 3;
  28.             UndoI    = 1;    CutI    = 3;    CopyI    = 4;    PasteI    = 5;    ClearI    = 6;
  29.  
  30.         WindowID     = 128;                         { ID fenêtre de l'application        }
  31.         AboutID         = 129;                            { ID About                            }
  32.         AlertID         = 500;
  33.         
  34.         maxDisp         = 21;                            { Nombre de lignes affichées        }
  35.     
  36.         resumeMask    = $01;                            { suspend/resume mask                }
  37. var    
  38.     myWindow:                WindowPtr;            { ma fenêtre (qui est  un Dialog)    }
  39.     dragRect:                 Rect;                { limite les mouvmnt de la fenêtre    }
  40.     theScrollRect:            Rect;                { le rectangle d'affichage            }
  41.     TheScrollRgn:            RgnHandle;            { la region pour scrollRect }
  42.     myMenus:                 ARRAY [AppleMenu..EditMenu] OF MenuHandle;
  43.                                                  { la table des menus                }
  44.     gMac:                    SysEnvRec;            { machine…                            }
  45.     eventPending:            boolean;            { vrai si événement en attente        }
  46.     hasWNE:                    boolean;            { vrai si WaitNextEvent implémenté    }
  47.     foreGround:                boolean;            { vrai si en foreGround                }
  48.  
  49.     doneFlag:                 BOOLEAN;            { signale la fin de l'application     }
  50.     myEvent:                 EventRecord;        { événement Macintosh                }
  51.     
  52.     whichChar:                 char;                { caractère clavier    Macintosh        }
  53.     
  54.     myRefNum:                integer;            { ID unique de l'appl. donné par MS }
  55.     
  56.     tname:                    array[typeNote..typeDead] 
  57.                                 of string[8];    { Noms des événements MidiShare        }
  58.     pname:                    array[0..1]         
  59.                                 of string[7];    { Noms des ports Midi                }
  60.     
  61.     myFinfo:                fontInfo;            { info relatives aux Fonts            }
  62.     myGrafPort:                grafPort;            { GrafPort en dehors de l'écran        }
  63.     myGrafPtr:                grafPtr;            { pointeur sur ce GrafPort            }
  64.  
  65.  
  66.  
  67. (********************************************************************************)
  68. (*                                 UTILITAIRES                                        *)
  69. (*------------------------------------------------------------------------------*)
  70. (* Routines pour MultiFinder                                                      *)
  71. (*                                                                                 *)
  72. (********************************************************************************)
  73.  
  74. {$S Initialize}
  75. Function TRAPAVAILABLE (tNumber: integer; tType: trapType): boolean;
  76. (*    Vérification de l'implémentation d'une trappe                                *)
  77. begin
  78.     TrapAvailable:= NGetTrapAddress(tNumber,tType) <> GetTrapAddress(_Unimplemented)
  79. end;
  80.  
  81. {$S Main}
  82. Function ISAPPWINDOW (aWind: windowPtr): boolean;
  83. (* vérifie si la fenêtre appartient à l'application                                *)
  84. begin
  85.     if aWind = nil then
  86.         IsAppWindow:= false
  87.     else 
  88.         IsAppWindow:= windowPeek(aWind)^.windowKind >= 0
  89. end;
  90.  
  91. {$S Main}
  92. Function ISDAWINDOW (aWind: windowPtr): boolean;
  93. (* vérifie si la fenêtre appartient à un accessoire de bureau                    *)
  94. begin
  95.     if aWind = nil then
  96.         IsDAWindow:= false
  97.     else 
  98.         IsDAWindow:= windowPeek(aWind)^.windowKind < 0
  99. end;
  100.  
  101. {$S Main}
  102. Procedure CenterRectOnScreen (var aRect: Rect);
  103. { aRect rectangle global à centrer sur écran (dragRect)                    }
  104. var    screenSize    : Point;
  105.     rectSize    : Point;
  106. begin
  107.     with dragRect do
  108.         SetPt(screenSize,right - left,bottom - top);
  109.     with aRect do begin
  110.         SetPt(rectSize,right - left,bottom - top);
  111.         left:= dragRect.left + (screenSize.h - rectSize.h) div 2;
  112.         top:= dragRect.top + (screenSize.v - rectSize.v) div 5;
  113.         topLeft:= point(PinRect(dragRect,topLeft));
  114.         right:= left + rectSize.h;
  115.         bottom:= top + rectSize.v;
  116.         end;
  117. end;
  118.  
  119. {$S Main}
  120. Function GetNewCenteredDialog (dialogID: integer): DialogPtr;
  121. var    dlogTemplate    : DialogTHndl;
  122. begin
  123.     GetNewCenteredDialog := nil;
  124.     dlogTemplate := DialogTHndl(GetResource('DLOG', dialogID));
  125.     if dlogTemplate <> nil then begin
  126.         CenterRectOnScreen(dlogTemplate^^.boundsRect);
  127.         GetNewCenteredDialog:= GetNewDialog(dialogID, nil, pointer(-1));
  128.         end
  129.     else SysBeep(2)                                                { At least give some indication }
  130. end;
  131.  
  132. {$S Main}
  133. Procedure AlertUser (alertID: integer);
  134. var    alrtTemplate    : AlertTHndl;
  135.     temp            : integer;
  136. begin
  137.     alrtTemplate := AlertTHndl(GetResource('ALRT', alertID));
  138.     if alrtTemplate <> nil then begin
  139.         SetCursor(arrow);
  140.         CenterRectOnScreen(alrtTemplate^^.boundsRect);
  141.         temp:= Alert(alertID,nil)
  142.         end
  143.     else SysBeep(2)                                             { At least give some indication        }
  144. end;
  145.  
  146.  
  147. (********************************************************************************)
  148. (*                                 SHOW ABOUT                                        *)
  149. (*------------------------------------------------------------------------------*)
  150. (* Affiche le About de l'application.                                             *)
  151. (*                                                                                 *)
  152. (* Les paramètres de l'appel :                                                    *)
  153. (* ---------------------------                                                    *)
  154. (*                                                                                 *)
  155. (*        aucun paramètre.                                                        *)
  156. (*                                                                                 *)
  157. (********************************************************************************)
  158.  
  159. {$S Main}
  160. Procedure SHOWABOUT;
  161. var    myDialog    : dialogPtr;
  162.     hit            : integer;
  163. begin
  164.     myDialog:= GetNewCenteredDialog(AboutID);
  165.     if myDialog <> nil then begin
  166.         ModalDialog(nil,hit);
  167.         DisposDialog(myDialog);
  168.         end
  169. end;
  170.         
  171.         
  172. (********************************************************************************)
  173. (*                                 INIT EVENT NAMES                                *)
  174. (*------------------------------------------------------------------------------*)
  175. (* Initialise les tables des noms des événements et des ports Midi tels qu'ils    *)
  176. (* doivent être affichés.                                                        *)
  177. (*                                                                                 *)
  178. (* Les paramètres de l'appel :                                                    *)
  179. (* ---------------------------                                                    *)
  180. (*                                                                                 *)
  181. (*        aucun paramètre.                                                        *)
  182. (*                                                                                 *)
  183. (********************************************************************************)
  184.  
  185. {$S Initialize}
  186. procedure InitEventNames;
  187. var    i:    integer;
  188. begin
  189.     pname[0]:='   M/';                            { nom du port Modem                    }
  190.     pname[1]:='   P/';                            { nom du port Imprimante            }
  191.     
  192.     for i := typePrivate to typeDead-1             { pas de nom pour ces codes            }
  193.         do tname[i] :=            ' Undef  ';
  194.     tname[typeNote]         := ' Note   ';        { donne un nom à tous les types        }
  195.     tname[typeKeyOn]         := ' KeyOn  ';        { d'événements MidiShare.            }
  196.     tname[typeKeyOff]         := ' KeyOff ';
  197.     tname[typeKeyPress]     := ' KPress ';
  198.     tname[typeCtrlChange]     := ' CtrlCh ';
  199.     tname[typeProgChange]     := ' ProgCh ';
  200.     tname[typeChanPress]     := ' CPress ';
  201.     tname[typePitchWheel]     := ' PWheel ';
  202.     tname[typeSongPos]         := ' SgPos  ';
  203.     tname[typeSongSel]         := ' SgSel  ';
  204.     tname[typeClock]         := ' Clock  ';
  205.     tname[typeStart]         := ' Start  ';
  206.     tname[typeContinue]         := ' Cont   ';
  207.     tname[typeStop]             := ' Stop   ';
  208.     tname[typeTune]         := ' Tune   ';
  209.     tname[typeActiveSens]     := ' ASens  ';
  210.     tname[typeReset]         := ' Reset  ';
  211.     tname[typeSysEx]         := ' SysEx  ';
  212.     tname[typeStream]         := ' Stream ';
  213.     tname[typeQuarterFrame]    := ' QFrame ';
  214.     tname[typeDead]         := ' Dead   ';
  215. end;
  216.  
  217.  
  218. (********************************************************************************)
  219. (*                                 TIME TO STRING                                    *)
  220. (*------------------------------------------------------------------------------*)
  221. (* Routine de conversion d'une date sur 32 bits en une chaine de caractères au    *)
  222. (* format heures, minutes, secondes et milliemes (HH:MN:SS.MMM)                    *)
  223. (*                                                                                 *)
  224. (* Les paramètres de l'appel :                                                    *)
  225. (* ---------------------------                                                    *)
  226. (*                                                                                 *)
  227. (*        t    :    la date à convertir.                                            *)
  228. (*        s    :    la chaine de caractères résultante                                *)
  229. (*                                                                                 *)
  230. (********************************************************************************)
  231.  
  232. {$S Main}
  233. procedure timeToString(t: longint; var s: str255);
  234. var    z:    integer;
  235. begin
  236.     z := ord('0');                                
  237.     s := '00:00:00.000';
  238.     s[12]:= char(z+(t mod 10)); t := t div 10;
  239.     s[11]:= char(z+(t mod 10)); t := t div 10;
  240.     s[10]:= char(z+(t mod 10)); t := t div 10;
  241.     
  242.     s[8]:= char(z+(t mod 10)); t := t div 10;
  243.     s[7]:= char(z+(t mod 6)); t := t div 6;
  244.     
  245.     s[5]:= char(z+(t mod 10)); t := t div 10;
  246.     s[4]:= char(z+(t mod 6)); t := t div 6;
  247.     
  248.     s[2]:= char(z+(t mod 10)); t := t div 10;
  249.     s[1]:= char(z+(t mod 10)); t := t div 10;
  250. end;
  251.  
  252.  
  253. (********************************************************************************)
  254. (*                                 EV TO STRING                                    *)
  255. (*------------------------------------------------------------------------------*)
  256. (* Routine de conversion d'un événement MidiShare en une chaine de caractères     *)
  257. (* au format date, port, canal, type d'événement et données complémentaires.    *)
  258. (*                                                                                 *)
  259. (* Les paramètres de l'appel :                                                    *)
  260. (* ---------------------------                                                    *)
  261. (*                                                                                 *)
  262. (*        e    :    pointeur sur l'événement à convertir.                            *)
  263. (*        s    :    la chaine de caractères résultante                                *)
  264. (*                                                                                 *)
  265. (********************************************************************************)
  266.  
  267. {$S Main}
  268. procedure EvToString(e: midiEvPtr; var s: str255);
  269. var i:    integer;
  270.     t:    str255;
  271.     n:    longint;
  272. begin
  273.     timeToString(e^.date,s);                                    { date                }
  274.     if e^.port <= printerPort then                                 { port /            }
  275.         s:= Concat(s,pname[e^.port])
  276.     else begin
  277.         numToString(e^.port,t);
  278.         if e^.port < 10 then s:= Concat(s,'   ',t,'/')
  279.         else if e^.port < 100 then s:= Concat(s,'  ',t,'/')
  280.         end;
  281.     numToString(e^.chan + 1,t);                                    { canal                }
  282.     if e^.chan < 10 then
  283.         s:= Concat(s,t,'  ',tname[e^.evType],'(')                { type                }
  284.     else s:= Concat(s,t,' ',tname[e^.evType],'(');
  285.     
  286.     n := midiCountFields(e) - 1;
  287.     for i:= 0 to n do begin
  288.         numToString(midiGetField(e,i),t);                        { champs            }
  289.         s:= Concat(s,t);
  290.         if Ord(s[0]) >= 42 then begin
  291.             if (Ord(s[0]) > 42) | (i < n) then begin
  292.                 s[0]:= Chr(42);
  293.                 s[42]:= '…'
  294.                 end;
  295.             leave
  296.             end
  297.         else if i <> n then
  298.             s:= Concat(s,' ')
  299.         end;
  300.     s:= Concat(s,')')
  301. end;
  302.  
  303.  
  304. (********************************************************************************)
  305. (*                                 DRAW MY CONTENT                                    *)
  306. (*------------------------------------------------------------------------------*)
  307. (* Copie le contenu de la bitMap hors écran, dans la fenêtre.                    *)
  308. (*                                                                                 *)
  309. (* Les paramètres de l'appel :                                                    *)
  310. (* ---------------------------                                                    *)
  311. (*                                                                                 *)
  312. (*        aucun paramètre.                                                        *)
  313. (*                                                                                 *)
  314. (********************************************************************************)
  315.  
  316. {$S Main}
  317. procedure drawMyContent;
  318. begin
  319.     copyBits(myGrafPort.portBits, myWindow^.portBits,theScrollRect,theScrollRect,srcCopy,Nil)
  320. end;
  321.  
  322.  
  323. (********************************************************************************)
  324. (*                                 DRAW MY WINDOW                                    *)
  325. (*------------------------------------------------------------------------------*)
  326. (* Affiche la fenêtre (qui est un Dialog) avec son contenu.                        *)
  327. (*                                                                                 *)
  328. (* Les paramètres de l'appel :                                                    *)
  329. (* ---------------------------                                                    *)
  330. (*                                                                                 *)
  331. (*        aucun paramètre.                                                        *)
  332. (*                                                                                 *)
  333. (********************************************************************************)
  334.  
  335. {$S Main}
  336. procedure drawMyWindow;
  337. begin    
  338.     DrawDialog(myWindow);
  339.     DrawMyContent
  340. end;              
  341.  
  342.  
  343. (********************************************************************************)
  344. (*                                 NEW LINE                                        *)
  345. (*------------------------------------------------------------------------------*)
  346. (* Positionne le point courant du GrafPort en début de ligne suivante et scroll    *)
  347. (* la bitMap arrivé à la dernière ligne.                                        *)
  348. (*                                                                                 *)
  349. (* Les paramètres de l'appel :                                                    *)
  350. (* ---------------------------                                                    *)
  351. (*                                                                                 *)
  352. (*        aucun paramètre.                                                        *)
  353. (*                                                                                 *)
  354. (********************************************************************************)
  355.  
  356. {$S Main}
  357. Procedure NewLine;
  358. var    d:    integer;
  359.     p:    point;
  360. begin
  361.     getPen(p);                                    { prend la position actuelle.        }
  362.     d := p.v+12+myFinfo.descent+myFinfo.leading;{ voit si une nouvelle ligne tient    }
  363.     if d > theScrollRect.bottom then begin        { si ce n'est pas le cas :            }
  364.         ScrollRect(theScrollRect,0,-12,theScrollRgn);    {  fait défiler la BitMap    }
  365.         moveTo(15,p.v)                            {  va à la dernière ligne            }
  366.     end else                                     { sinon:                            }
  367.         moveTo(15,p.v+12);                        {  va à la ligne suivante            }
  368. end;
  369.  
  370.  
  371. (********************************************************************************)
  372. (*                             TREAT MIDI EVENTS                                    *)
  373. (*------------------------------------------------------------------------------*)
  374. (* La procedure TreatMidiEvents et chargée de la réception des événements Midi. *)
  375. (* Elle est appelée périodiquement, dans la boucle principale du programme.        *) 
  376. (*                                                                                 *)
  377. (* TreatMidiEvents va consulter le fifo de réception de l'application et         *)
  378. (* afficher les événements qui si trouvent.    Suivant la rapidité du flot Midi     *)
  379. (* l'application peut prendre du retard et accumuler trop d'événements dans son    *)
  380. (* fifo. Dans ce cas, les événements exédentaires sont tout simplement détruits.*)
  381. (*                                                                                 *)
  382. (* Les paramètres de l'appel :                                                    *)
  383. (* ---------------------------                                                    *)
  384. (*                                                                                 *)
  385. (*        aucun paramètre.                                                        *)
  386. (*                                                                                 *)
  387. (********************************************************************************)
  388.  
  389. {$S Main}
  390. procedure treatMidiEvents;
  391. var    n,i:    integer;
  392.     s:        str255;
  393.     e:        midiEvPtr;
  394.     
  395.     function     Min(n1,n2: longint): longint;
  396.     begin
  397.         if n1<n2 then min := n1 else min := n2
  398.     end;
  399.  
  400. begin
  401.     n := MidiCountEvs(myRefNum);                { Compte le nombre d'événements en attente    }
  402.     while n > maxDisp do begin                    { Si trop d'événements ont été accumulés    }
  403.         MidiFreeEv(midiGetEv(myRefNum));        {  on en détruit pour rattraper le retard.    }
  404.         n := n-1;
  405.     end;
  406.     if n>0 then begin                            { S'il y a des événements à afficher :        }
  407.         setPort(myGrafPtr);                        {  on se prépare à dessiner hors écran,        }
  408.         for i := 1 to min(n,3) do begin            {  on ne traite pas plus de 3 Ev à la fois    }
  409.             e := midiGetEv(myRefNum);            {  on récupère l'événement dans le fifo        }
  410.             evToString(e,s);                    {  conversion de l'Ev en chaine de car.        }
  411.             midiFreeEv(e);                        {  on pense bien à libérer l'événement        }
  412.             newLine;                            {  ligne suivante, avec un eventuel scroll    }
  413.             drawString(s);                        {  affiche hors écran.                        }
  414.         end;                                    
  415.         setPort(myWindow);                        { Retour au dessin sur l'écran.                }
  416.         drawMyContent;                            { Affichage véritable.                        }
  417.     end
  418. end;
  419.  
  420.  
  421. (********************************************************************************)
  422. (*                                 SET UP MIDI                                        *)
  423. (*------------------------------------------------------------------------------*)
  424. (* Cette procédure définit les différents paramètres necessaires au fonction-    *)
  425. (* nement Midi de l'application. Tout d'abord, le MidiOpen de l'application        *)
  426. (* qui lui permet de se signaler à MidiShare, et d'obtenir un numèro de réfé-    *)
  427. (* rence unique pour la suite des opérations. La chaine de caractères passée en    *)
  428. (* argument sert au catalogue des applications ouvertes que maintient MidiShare.*)
  429. (* Ensuite l'établissement d'une connection qui va relier l'entrée de l'appli-    *)
  430. (* cation aux ports Midi d'arrivée.    Enfin la création d'une table de corres-    *)
  431. (* pondance entre les codes et noms des événements reçus.                        *)
  432. (*                                                                                 *)
  433. (* Les paramètres de l'appel :                                                    *)
  434. (* ---------------------------                                                    *)
  435. (*                                                                                 *)
  436. (*        aucun paramètre.                                                        *)
  437. (*                                                                                 *)
  438. (********************************************************************************)
  439.  
  440. {$S Initialize}
  441. procedure SetUpMidi;
  442. var    name:        str255;
  443.     apRefNum:    integer;
  444.     apParam:    Handle;
  445.     aRefNum:    integer;
  446.  
  447.     Procedure FAILSETUP (strIndex: integer);
  448.     var    msgStr:    str255;
  449.     begin
  450.         GetIndString (msgStr,AlertID,strIndex);        { message d'alerte suivant erreur    }
  451.         ParamText(name,msgStr,'','');
  452.         AlertUser(AlertID);
  453.         ExitToShell                                    { et quitte                            }
  454.     end;
  455.     
  456. begin
  457.     GetAppParms(name,apRefNum,apParam);                { récupérer le nom d'application    }
  458.     if not MidiShare then FailSetUp(1);                { MidiShare n'est pas installé        }
  459.         
  460.     myRefNum:= MidiOpen(name);                        { ouverture en Midi                    }
  461.     if myRefNum = MidiErrSpace then FailSetUp(2);    { impossible, plus de place            }
  462.     
  463.     midiConnect(0,myRefNum,true);            { connection avec les ports Midi d'entrées    }
  464.     InitEventNames;                            { création de la table des noms.            }
  465. end;
  466.     
  467.     
  468. (********************************************************************************)
  469. (*                             SET UP WINDOWS                                        *)
  470. (*------------------------------------------------------------------------------*)
  471. (* Procédure chargé d'ouvrir la fenêtre et de réaliser les initialisations         *)
  472. (* necessaires. Ici l'affichage est un peu spécial, il se fait tout d'abord sur    *)
  473. (* une BitMap hors écran, qui est ensuite copiée sur l'écran.                    *)
  474. (*                                                                                *)
  475. (* Les paramètres de l'appel :                                                    *)
  476. (* ---------------------------                                                    *)
  477. (*                                                                                 *)
  478. (*        aucun paramètre.                                                        *)
  479. (*                                                                                 *)
  480. (********************************************************************************)
  481.  
  482. {$S Initialize}
  483. procedure SetUpWindows;
  484. var    r    : rect;
  485. begin
  486.     setRect(theScrollRect,11, 24, 274, 278);    { définition des coord. du rect. d'affichage}    
  487.     theScrollRgn := newRgn;                        { alloue la region de scroll                }
  488.     myGrafPtr := @myGrafPort;                    { définition d'un GrafPort hors de l'écran    }
  489.     openPort(myGrafPtr);                        { ouverture du grafPort                        }
  490.     with myGrafPtr^.portBits do begin            { définition de sa bitMap                    }
  491.         baseAddr := newPtr(40*40*8);            {  taille de 320 x 320                        }        
  492.         rowBytes := 40;                            {  soit 40 octets par lignes                }
  493.         bounds := theScrollRect                    {  avec les coordonnées définies plus haut    }
  494.     end;
  495.     setPort(myGrafPtr);                            { On en fait le port courant :                }
  496.     textFont(Monaco);textSize(9);                {  choix de divers paramètres d'écriture    }
  497.     textMode(srcCopy); PenNormal;                {  et de dessin.                            }
  498.     eraseRect(theScrollRect);                    {  efface la totalité de la bitMap.            }
  499.     moveTo(15,21);                                {  position au dessus de la 1er ligne        }
  500.     
  501.     with screenBits.bounds do                    { rect max de déplacmt de fenêtre            }
  502.         SetRect(dragRect, 4, 24, right - 4, bottom - 4);
  503.     myWindow := GetNewDialog(WindowID,nil,pointer(-1));
  504.     SetPort(myWindow);
  505.     textFont(Monaco);textSize(9);                {  choix de divers paramètres d'écriture    }
  506.     textMode(srcCopy); PenNormal;                {  et de dessin.                            }
  507.     GetFontInfo(myFinfo);                        {  pour connaitre la hauteur des lignes        }
  508.     
  509.     r:= myWindow^.portRect;
  510.     with r do begin
  511.         LocalToGlobal(topLeft);
  512.         LocalToGlobal(botRight)
  513.         end;
  514.     if not RectInRgn(r,GetGrayRgn) then begin    { fenêtre hors écran : centrée                }
  515.         CenterRectOnScreen(r);
  516.         MoveWindow(myWindow,r.left,r.top,true)
  517.         end;
  518.     ShowWindow(myWindow)
  519. end;
  520.  
  521.  
  522. {$S Main}
  523. Procedure SaveWindowPos;
  524. type    rectPtr  =     ^rect;
  525.         rectHdle =    ^rectPtr;
  526. var    windHdle:    handle;
  527. begin
  528.     windHdle:= Get1Resource('DLOG',WindowID);
  529.     rectHdle(windHdle)^^:= windowPeek(myWindow)^.contRgn^^.rgnBBox;
  530.     ChangedResource(windHdle);
  531.     if ResError = noErr then
  532.         WriteResource(windHdle)
  533. end;
  534.     
  535.  
  536. (********************************************************************************)
  537. (*                                 SET UP MENUS                                    *)
  538. (*------------------------------------------------------------------------------*)
  539. (* Définition de la barre des menus.                                             *)
  540. (*                                                                                 *)
  541. (* Les paramètres de l'appel :                                                    *)
  542. (* ---------------------------                                                    *)
  543. (*                                                                                 *)
  544. (*        aucun paramètre.                                                        *)
  545. (*                                                                                 *)
  546. (********************************************************************************)
  547.  
  548. {$S Initialize}
  549. Procedure SetUpMenus;
  550. var    i:    integer;
  551. begin    
  552.     myMenus[AppleMenu] := GetMenu(AppleID);
  553.     AddResMenu(myMenus[AppleMenu], 'DRVR');
  554.     myMenus[FileMenu] := GetMenu(FileID);    
  555.     myMenus[EditMenu] := GetMenu(EditID);            { menu Edit                            }
  556.     FOR i := AppleMenu TO EditMenu DO
  557.         InsertMenu(myMenus[i], 0);
  558.     DrawMenuBar  
  559. end;
  560.  
  561.  
  562. (********************************************************************************)
  563. (*                                 INITIALIZE                                        *)
  564. (*------------------------------------------------------------------------------*)
  565. (* Initialisations générales (hasWNE, foreGround, managers, fenêtre, Midi)        *)
  566. (*                                                                                 *)
  567. (* Les paramètres de l'appel :                                                    *)
  568. (* ---------------------------                                                    *)
  569. (*                                                                                 *)
  570. (*        aucun                                                                    *)
  571. (*                                                                                 *)
  572. (********************************************************************************)
  573.  
  574. {$S Initialize}
  575. Procedure INITIALIZE;
  576. var    err:    OSErr;
  577. begin
  578.     err:= SysEnvirons(1,gMac);
  579.     hasWNE:= (gMac.machineType >= 0) & TrapAvailable(_WaitNextEvent,ToolTrap);
  580.         
  581.     InitGraf(@thePort);                                { initialisations standard            }
  582.     InitFonts;
  583.     InitWindows;
  584.     InitMenus;
  585.     TEInit;
  586.     InitDialogs(NIL);
  587.     InitCursor;
  588.     SetUpMenus;                                        { mise en place menus                }
  589.     SetUpMidi;                                        { ouverture MidiShare                }
  590.     SetUpWindows;                                    { initialisations fenêtre et listes    }
  591. end;
  592.  
  593.  
  594. (********************************************************************************)
  595. (*                                 ADJUST MENUS                                    *)
  596. (*------------------------------------------------------------------------------*)
  597. (* Ajustement de la barre de menus suivant la fenêtre de premier plan, juste    *)
  598. (* lors d'un click dans la barre des menus                                        *)
  599. (*                                                                                 *)
  600. (* Les paramètres de l'appel :                                                    *)
  601. (* ---------------------------                                                    *)
  602. (*                                                                                 *)
  603. (*        aucun                                                                    *)
  604. (*                                                                                 *)
  605. (********************************************************************************)
  606.  
  607. {$S Main}
  608. Procedure ADJUSTMENUS;
  609. begin
  610.     if IsAppWindow(FrontWindow) then begin
  611.         DisableItem(myMenus[EditMenu],UndoI);
  612.         DisableItem(myMenus[EditMenu],CutI);
  613.         DisableItem(myMenus[EditMenu],CopyI);
  614.         DisableItem(myMenus[EditMenu],PasteI);
  615.         DisableItem(myMenus[EditMenu],ClearI)
  616.         end
  617.     else
  618.     if IsDAWindow(FrontWindow) then begin
  619.         EnableItem(myMenus[EditMenu],UndoI);
  620.         EnableItem(myMenus[EditMenu],CutI);
  621.         EnableItem(myMenus[EditMenu],CopyI);
  622.         EnableItem(myMenus[EditMenu],PasteI);
  623.         EnableItem(myMenus[EditMenu],ClearI)
  624.         end
  625. end;
  626.             
  627.  
  628. (********************************************************************************)
  629. (*                                 DO COMMAND                                        *)
  630. (*------------------------------------------------------------------------------*)
  631. (* Execution des commandes du menu.                                                 *)
  632. (*                                                                                 *)
  633. (* Les paramètres de l'appel :                                                    *)
  634. (* ---------------------------                                                    *)
  635. (*                                                                                 *)
  636. (*        mResult     :    le menu et l'item sélectionnés                            *)
  637. (*                                                                                 *)
  638. (********************************************************************************)
  639.  
  640. {$S Main}
  641. Procedure DOCOMMAND ( mResult: LONGINT);
  642. var    theItem:    integer;
  643.     name:        str255;
  644.     sysEdit:    boolean;
  645.     
  646. begin    
  647.     theItem := LoWord(mResult);
  648.     case HiWord(mResult) of
  649.         AppleID:
  650.             if theItem <> 1 then begin
  651.                 GetItem(myMenus[AppleMenu], theItem, name);
  652.                 theItem := OpenDeskAcc(name)  end
  653.             else showAbout;
  654.         FileID:    
  655.             doneFlag := TRUE;
  656.         EditID:                                        { menu Edit: uniquement pour DAs    }
  657.             sysEdit := SystemEdit(theItem-1);
  658.     end;
  659.     HiliteMenu(0)  
  660. end;
  661.         
  662.  
  663. (********************************************************************************)
  664. (*                                 DO MOUSE DOWN                                    *)
  665. (*------------------------------------------------------------------------------*)
  666. (* Gère les clicks souris                                                        *)
  667. (*                                                                                 *)
  668. (* Les paramètres de l'appel :                                                    *)
  669. (* ---------------------------                                                    *)
  670. (*                                                                                 *)
  671. (*        anEvent: l'événement                                                    *)
  672. (*                                                                                 *)
  673. (********************************************************************************)
  674.  
  675. {$S Main}
  676. Procedure DOMOUSEDOWN (anEvent: eventRecord);
  677. var    whichWind:    windowPtr;
  678.     part:        integer;
  679. begin
  680.     part:= FindWindow(anEvent.where, whichWind);
  681.     case part of
  682.         inMenuBar:        begin
  683.                         AdjustMenus;
  684.                         DoCommand(MenuSelect(anEvent.where))
  685.                         end;
  686.         inSysWindow:    SystemClick(anEvent,whichWind);
  687.         inDrag:         DragWindow(whichWind,anEvent.where,dragRect);
  688.         inGoAway:        if IsAppWindow(whichWind) then 
  689.                             doneFlag:= TrackGoAway(whichWind,anEvent.where);
  690.         inContent:        if whichWind <> FrontWindow then
  691.                             SelectWindow(whichWind);
  692.         end
  693. end;
  694.  
  695.  
  696. (********************************************************************************)
  697. (*                                 ADJUST CURSOR                                    *)
  698. (*------------------------------------------------------------------------------*)
  699. (* Ajuste le curseur suivant région et fenêtre                                    *)
  700. (*                                                                                 *)
  701. (********************************************************************************)
  702.  
  703. {$S Main}
  704. Procedure ADJUSTCURSOR;
  705. begin
  706.     if foreGround and IsAppWindow(FrontWindow) then
  707.         SetCursor(arrow)
  708. end;
  709.  
  710.  
  711. (********************************************************************************)
  712. (*                                 CLOSE WINDOWS                                    *)
  713. (*------------------------------------------------------------------------------*)
  714. (* Pour terminer correctement l'application: fermeture de toutes les fenêtres    *)
  715. (* (application et DA's)                                                        *)
  716. (*                                                                                 *)
  717. (********************************************************************************)
  718.  
  719. {$S Main}
  720. Procedure CLOSEWIND (aWind: windowPtr);
  721. (* ferme une fenêtre                                                            *)
  722. begin
  723.     if IsDAWindow(aWind) then
  724.         CloseDeskAcc(windowPeek(aWind)^.windowKind)
  725.     else if IsAppWindow(aWind) then
  726.         DisposeWindow(aWind)
  727. end;
  728.  
  729. Procedure CLOSEALLWINDS;
  730. (* ferme toutes les fenêtres                                                    *)
  731. var    window:    windowPtr;
  732. begin
  733.     repeat
  734.         window:= FrontWindow;
  735.         if window <> nil then
  736.             CloseWind(window);
  737.     until window = nil;
  738. end;
  739.  
  740.  
  741. Procedure _DataInit;        EXTERNAL;
  742.  
  743. (********************************************************************************)
  744. (*                         Corps principal du programme                            *)
  745. (*------------------------------------------------------------------------------*)
  746. (* Ouverture des différents managers, Initialisations diverses et boucle prin-    *)
  747. (* cipale typique d'une application Macintosh.                                     *)
  748. (********************************************************************************)
  749.     
  750. {$S Main}
  751. begin
  752.     UnLoadSeg(@_DataInit);
  753.     MaxApplZone;
  754.     Initialize;
  755.     UnLoadSeg(@Initialize);
  756.     
  757.     DoneFlag:=false;                                { flag de terminaison                }
  758.     repeat                                            { boucle principale typique            }
  759.         if hasWNE then
  760.             eventPending:= WaitNextEvent(everyEvent, myEvent, 20, nil)
  761.                                                     { no sleep, no mouseRgn                }
  762.         else begin
  763.             SystemTask;
  764.              eventPending:= GetNextEvent(everyEvent, myEvent)
  765.         end;
  766.         AdjustCursor;                                { si ≠ curseurs ou mouseRgn, ici    }
  767.         with myEvent do
  768.             case what of
  769.                 nullEvent:
  770.                     treatMidiEvents;
  771.                 osEvt:
  772.                     case BSR(message,24) of
  773.                         suspendResumeMessage:
  774.                             foreGround:= BAnd(message,resumeMask) <> 0;
  775.                         mouseMovedMessage:
  776.                             treatMidiEvents;
  777.                     end;
  778.                   keyDown, autoKey:
  779.                     IF IsAppWindow(FrontWindow) then begin
  780.                           whichChar := CHR(BAnd(message, charCodeMask));
  781.                          IF BAnd(modifiers, cmdKey) <> 0 then
  782.                             DoCommand(MenuKey(whichChar))  
  783.                     end;
  784.                 mouseDown: 
  785.                     DoMouseDown(myEvent);
  786.                   updateEvt:
  787.                     if IsAppWindow(windowPtr(message)) then begin
  788.                         BeginUpdate(windowPtr(message));
  789.                         if not EmptyRgn(windowPtr(message)^.visRgn) then begin
  790.                             SetPort(windowPtr(message));
  791.                             drawMyWindow
  792.                             end;
  793.                         EndUpdate(windowPtr(message))
  794.                     end
  795.             end
  796.     UNTIL doneFlag;
  797.     disposeRgn(theScrollRgn);
  798.     MidiClose(myRefNum);                    { signale à MidiShare la fin de l'application    }
  799.     SaveWindowPos;
  800.     CloseAllWinds;
  801.     ExitToShell
  802. end.